'''
Created on Jan 29, 2013

@author: drelfi
'''

PROXY_HOST = "localhost"
PROXY_PORT = 8080
COUCHBASE_USER = "Administrator"

################################################
## Util class
################################################
import time    
class Timer:
    def __enter__(self):
        self.start = time.clock()
        return self

    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start


'''
Selenium section
'''
def runSelenium(url, noproxy = False):
    '''
    Running instance of firefox against our proxy
    '''
    from selenium import webdriver
    from twisted.internet import reactor
    from metrics.http_statistics import GlobalHttpMetrics
    from storage.db_connection import DBConnection
    import sys
    
    if noproxy:
        br = webdriver.Firefox()
    else:
        fp = webdriver.FirefoxProfile()
        fp.set_preference("network.proxy.type", 1)
        fp.set_preference("network.proxy.http", PROXY_HOST)
        fp.set_preference("network.proxy.http_port", PROXY_PORT)
        fp.set_preference("network.proxy.ftp", PROXY_HOST)
        fp.set_preference("network.proxy.ftp_port", PROXY_PORT)
        fp.set_preference("network.proxy.ssl", PROXY_HOST)
        fp.set_preference("network.proxy.ssl_port", PROXY_PORT)
        fp.set_preference("network.proxy.no_proxies_on", "localhost,127.0.0.1") 
        br = webdriver.Firefox(firefox_profile=fp)
    
    with Timer() as t:
        br.get(url)
    
    GlobalHttpMetrics.getInstance().url = url    
    GlobalHttpMetrics.getInstance().timeElapsed = t.interval
    br.close()

    '''Storing objects'''
    try:
        DBConnection.getInstance().flushCache()
    except:
        print "Couldn't flush: ", sys.exc_info()

    reactor.stop()

'''
Proxy section
'''    
def proxy(url, logEnabled = False, secure = False):
    from twisted.python import log
    import sys
    from twisted.internet import endpoints, reactor
    portstr = "tcp:%d:interface=%s" % (PROXY_PORT, PROXY_HOST)# serve on localhost:8080

    def shutdown(reason, reactor, stopping=[]):
        """Stop the reactor."""
        if stopping: return
        stopping.append(True)
        if reason:
            log.msg(reason.value)
        reactor.callWhenRunning(reactor.stop)

    if logEnabled:
        log.startLogging(sys.stdout)
    endpoint = endpoints.serverFromString(reactor, portstr)
    # If twisted supports SSL, ssl support can be enabled
    if secure:
        from proxy.proxy_client_ssl import TunnelProxyFactory
        d = endpoint.listen(TunnelProxyFactory())
    else:
        from proxy.proxy_client import CacheProxyFactory
        d = endpoint.listen(CacheProxyFactory())
    
    d.addErrback(shutdown, reactor)
    
    reactor.callInThread( runSelenium, url)
    reactor.run()




def usage():
    print( """\
HTTP Cache Finder
Usage: python cache_finder.py [OPTIONS]
-u/--url [url]       defines the url to connect to
-a/--analyze         analyzes caching options for URL
-l/--log             logging enabled
-s/--statistics      shows statistics about the URL connected to
-p/--password [pass] password for couchbase db (default = "" )
-d/--dbhost [host]   db host to store information (default = localhost:8091
--ssl                enable ssl proxy support
-h/--help            this message
""")


def main():
    import getopt, sys
    from metrics.http_statistics import GlobalHttpMetrics
    from storage.db_connection import DBConnection

    try:
        opts, args = getopt.getopt(sys.argv[1:], "u:lsp:d:a", ["url=","log","statistics","password=","dbhost=","analyze=","ssl"])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err) # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    url = ""
    log = False
    stats = False
    password = None
    db_host = None
    secure = False
    __analyze = False
    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-u", "--url"):
            url = a
        elif o in ("-p", "--password"):
            password = a
        elif o in ("-d", "--dbhost"):
            db_host = a
        elif o in ("-l", "--log"):
            log = True
        elif o in ("-s", "--statistics"):
            stats = True
        elif o in ("-a", "--analyze"):
            __analyze = True
        elif o == "--ssl":
            secure = True
        else:
            assert False, "unhandled option"
    #### If 
    if len(url) == 0:
        assert False, "URL cannot be null"

    ''' Initialize DB '''
    if password and db_host:
        DBConnection.getInstance().initialize( host = db_host, password = password )
    
    if __analyze:
        from analyze import analyze
        
        analyze(url)
    else:    
        proxy(url, log, secure)
    
        if stats:
            GlobalHttpMetrics.getInstance().stdPrint()
            
            '''Store the stats in our DB'''
            if DBConnection.getInstance().isConnected:
                DBConnection.getInstance().storeObject(GlobalHttpMetrics.getInstance())

'''
Main call
'''
if __name__ == '__main__':
    main()